# -*- coding: utf-8 -*-
# created on 2017/4/11

from mathsolver.functions.shuyushi import *


class MtEq(BaseFunction):
    def solver(self, *args):
        name = args[1].replace(":", "")
        if "任意" in args[-1] or "任何" in args[-1]:
            value = {"name": name, "value": args[0], "flag": "forall"}
        elif "存在" in args[-1]:
            value = {"name": name, "value": args[0], "flag": "exist"}
        else:
            value = {"name": name, "value": args[0], "flag": ""}

        if self.search(name):
            mingti = self.search(name)
            mingti.value["hypo"] = args[0]
            self.output.append(mingti)
        else:
            self.output.append(BaseMingTiInner(value))

        return self


class MtIneq(MtEq):
    pass


class MtIneqs(MtEq):
    pass


class MtBelong(MtEq):
    pass


class MtHypo(MtEq):
    @staticmethod
    def classify(item):
        if len(item) == 3:
            if any([op in item[1] for op in ["<", ">", "="]]):
                return BaseIneq(item)
            else:
                if item[-1] == "R":
                    item[-1] = S.Reals
                return BaseBelong(item)
        elif len(item) == 2:
            return BaseEq(item)
        else:
            return BaseIneqs(item)

    def solver(self, *args):
        name = args[1].replace(":", "")
        value = args[0].value
        value["name"] = name
        value["value"] = self.classify(value["condition"])
        if value["hypo"]:
            value["hypo"] = self.classify(value["hypo"])

        self.output.append(BaseMingTiInner(value))
        return self


class MtTof(BaseFunction):
    def solver(self, *args):
        m1, m2 = args[0].value, args[1].value
        m1 = self.search(m1).value["value"]
        m2 = self.search(m2).value["value"]
        text = args[2]
        if not isinstance(m1, BaseSymbolValue):
            try:
                m1_value = MathematicaSolve().solver(m1, BaseVariables(list(m1.free_symbols()))).output[0].value
            except Exception:
                m1_value = None
                # m1_value = MathematicaFindinstance().solver(m1).output[0].value
        else:
            m1_value = m1.value

        m2_value = None
        if not isinstance(m2, BaseSymbolValue):
            try:
                m2_value = MathematicaSolve().solver(m2, BaseVariables(list(m2.free_symbols()))).output[0].value
            except Exception:
                m1_value = None
                # m2_value = MathematicaFindinstance().solver(m2).output[0].value
        else:
            m2_value = m2.value

        answer = []
        chongfen = False
        biyao = False
        if m1_value and m2_value:
            v1 = m1_value.values()[0]
            v2 = m2_value.values()[0]
            if "充分必要" in text or "充要" in text:
                if m1_value == m2_value:
                    self.output.append(BaseVariable(True))
                else:
                    self.output.append(BaseVariable(False))
                return self

            if v1.intersection(v2) == v1:
                chongfen = True

            if v2.intersection(v1) == v2:
                biyao = True

            if "不充分" in text or "非充分" in text:
                answer.append(not chongfen)
            elif "充分" in text and chongfen is not None:
                answer.append(chongfen)

            if "不必要" in text or "非必要" in text:
                answer.append(not biyao)
            elif "必要" in text and biyao is not None:
                answer.append(biyao)

        else:
            if isinstance(m2, BaseSymbolValue):
                pass
            else:
                stepsolver = ShuYuShiTof002(known=m1_value).solver(m2)
                ans = stepsolver.output[0].value
                if "不充分" in text or "非充分" in text:
                    answer.append(not ans)
                else:
                    answer.append(ans)

            if isinstance(m1, BaseSymbolValue):
                pass
            else:
                stepsolver = ShuYuShiTof002(known=m2_value).solver(m1)
                ans = stepsolver.output[0].value
                if "不必要" in text or "非必要" in text:
                    answer.append(not ans)
                else:
                    answer.append(ans)
        if answer:
            self.output.append(BaseVariable(all(answer)))
        self.label.add("判断充分必要条件")
        return self


class MtNeg(MtHypo):
    @staticmethod
    def inverse_mapping(item):
        if len(item) == 2:
            return BaseIneq([item[0], "!=", item[1]]).printing()
        elif item[1] == ">":
            return BaseIneq([item[0], "<=", item[2]]).printing()
        elif item[1] == "<":
            return BaseIneq([item[0], ">=", item[2]]).printing()
        elif item[1] == "<=":
            return BaseIneq([item[0], ">", item[2]]).printing()
        elif item[1] == ">=":
            return BaseIneq([item[0], "<", item[2]]).printing()
        elif item[1] == "!=":
            return BaseEq([item[0], item[2]]).printing()
        elif item[1] == "∈":
            return BaseBelong([item[0], '\u2209', item[2]]).printing()
        elif item[1] == '\u2209':
            return BaseBelong([item[0], '∈', item[2]]).printing()

    def solver(self, *args):
        hypo = self.search(args[0].value).value
        flag = None
        if hypo["flag"] == "exist":
            flag = "\\forall"
        elif hypo["flag"] == "forall":
            flag = "\\exists"
        if isinstance(hypo["condition"], BaseValue):
            condition = hypo["condition"].printing()
        else:
            condition = self.classify(hypo["condition"]).printing()
        out = flag + " " + condition + "," + self.inverse_mapping(hypo["hypo"])
        self.steps.append(["%s的否命题是: %s" % (args[0].value, out), ""])
        self.label.add("求命题的否命题")
        return self


class MingFouding(MtNeg):
    def solver(self, *args):
        mingti = self.search(args[0].value).value
        if mingti["flag"] == "exist":
            flag = "\\forall"
        elif mingti["flag"] == "forall":
            flag = "\\exists"
        else:
            flag = ""
        out = flag + " " + mingti["value"].printing() + "," + self.inverse_mapping(mingti["hypo"].value)
        self.steps.append(["否定是: %s" % out, ""])
        self.label.add("求命题的否定")
        return self


class MtNiFou(MtNeg):
    def solver(self, *args):
        mingti = self.search(args[0].value).value
        if mingti["flag"] == "exist":
            flag = "\\forall"
        elif mingti["flag"] == "forall":
            flag = "\\exists"
        else:
            flag = ""
        out = flag + " " + self.inverse_mapping(mingti["hypo"].value) + "," + self.inverse_mapping(mingti["value"].value)
        self.steps.append(["逆否命题是: %s" % out, ""])
        self.label.add("求命题的逆否命题")
        return self


class MtUpdate(MtHypo):
    def solver(self, *args):
        args[0].value["value"] = self.classify(args[0].value["value"])
        self.output.append(args[0])
        return self


class MtTrueFalse(MtHypo):
    def solver(self, *args):
        self.label.add("判断命题的真假")
        return self


if __name__ == '__main__':
    pass
